#include "stdafx.h"
#include "game_engine.h"

#define MOUSE_WEEL_SENSIVITY			500.0f
#define MIN_CAMERA_DISTANCE				20.0f
#define MAX_CAMERA_DISTANCE				80.0f

namespace rpg {

	void GameEngine::processMouse(float deltaTime) {
		GameCamera *activeGameCamera = mGameLevel.getActiveCamera();
		const OIS::MouseState &ms = mMouse->getMouseState();

		mGuiSystem->injectMouseMove(ms.X.rel, ms.Y.rel);

		if(ms.buttonDown(OIS::MB_Left) && !mOldMouseState.buttonDown(OIS::MB_Left))
			mGuiSystem->injectMouseButtonDown(CEGUI::LeftButton);

		if(!ms.buttonDown(OIS::MB_Left) && mOldMouseState.buttonDown(OIS::MB_Left))
			mGuiSystem->injectMouseButtonUp(CEGUI::LeftButton);

		if(ms.buttonDown(OIS::MB_Right) && !mOldMouseState.buttonDown(OIS::MB_Right))
			mGuiSystem->injectMouseButtonDown(CEGUI::RightButton);

		if(!ms.buttonDown(OIS::MB_Right) && mOldMouseState.buttonDown(OIS::MB_Right))
			mGuiSystem->injectMouseButtonUp(CEGUI::RightButton);

		if(ms.buttonDown(OIS::MB_Middle) && !mOldMouseState.buttonDown(OIS::MB_Middle))
			mGuiSystem->injectMouseButtonDown(CEGUI::MiddleButton);

		if(!ms.buttonDown(OIS::MB_Middle) && mOldMouseState.buttonDown(OIS::MB_Middle))
			mGuiSystem->injectMouseButtonUp(CEGUI::MiddleButton);

		mMouseX += ms.X.rel;
		mMouseY += ms.Y.rel;

		if(mMouseX > mScreenWidth)
			mMouseX = mScreenWidth;
		if(mMouseX < 0)
			mMouseX = 0;

		if(mMouseY > mScreenHeight)
			mMouseY = mScreenHeight;
		if(mMouseY < 0)
			mMouseY = 0;

		/* TODO: mouse processing code */

		if(activeGameCamera != NULL) {
			if(ms.Z.rel > 0) {
				float distanceToTarget = activeGameCamera->getDistanceToTarget();

				if(distanceToTarget > MIN_CAMERA_DISTANCE) {
					activeGameCamera->setDistanceToTarget(distanceToTarget - deltaTime * MOUSE_WEEL_SENSIVITY);
				}
			}

			if(ms.Z.rel < 0) {
				float distanceToTarget = activeGameCamera->getDistanceToTarget();

				if(distanceToTarget < MAX_CAMERA_DISTANCE) {
					activeGameCamera->setDistanceToTarget(distanceToTarget + deltaTime * MOUSE_WEEL_SENSIVITY);
				}
			}

			if(ms.buttonDown(OIS::MB_Left)&&!mOldMouseState.buttonDown(OIS::MB_Left)) {
				float offsetX, offsetY;

				offsetX = float(mMouseX) / float(mScreenWidth);
				offsetY = float(mMouseY) / float(mScreenHeight);

				Ogre::Plane groundPlaneDesc(Ogre::Vector3::UNIT_Y, 0.0f);
				Ogre::Ray mouseRay = activeGameCamera->getOgreCamera()->getCameraToViewportRay(offsetX, offsetY);

				std::pair<bool, float> intersectResult = mouseRay.intersects(groundPlaneDesc);

				if(intersectResult.first) {
					Ogre::Vector3 point = mouseRay.getPoint(intersectResult.second);

					mCrossNode->setPosition(point);

					Actor *currentActor = mGameLevel.getActorByName("Game/Robo0");
					std::list<Ogre::Vector3> waypoint;
					Ogre::Vector3 currentMovePoint;

					if(!currentActor->isWaypointEmpty()) {
						currentMovePoint = currentActor->getCurrentMovePoint();
					} else {
						currentMovePoint = currentActor->getPosition();
					}

					mGameLevel.buildWaypoint(currentMovePoint, point, &waypoint);

					if(waypoint.size() > 0) {
						currentActor->clearWaypoint();
						currentActor->addListToWaypoint(&waypoint);
					}
				}
			}
		}

		mOldMouseState = ms;
	}

}